// -----------------------------
// Author: 		Dhaenens Gert	
// Creation: 	2/19/2015 9:38:44 PM				
// -----------------------------

#include "CTexture.h"

#include "CGraphicsDevice.h"

namespace Flow
{

	CTexture::CTexture()
		: m_lpTexture(nullptr)
		, m_lpShaderView(nullptr)
		, m_Width(0)
		, m_Height(0)
		, m_Format(TextureFormat::Unknown)
		, m_HasData(false)
	{
	}

	CTexture::~CTexture()
	{
		SafeReleaseInterface(&m_lpShaderView);
		SafeReleaseInterface(&m_lpTexture);
	}

	void CTexture::Release()
	{
		delete this;
	}

	Bool CTexture::Create(IGraphicsDevice* lpDevice, UInt32 uWidth, UInt32 uHeight, TextureFormat::Enum format, void* lpData)
	{
		CGraphicsDevice* lpCGraphicsDevice = static_cast<CGraphicsDevice*>(lpDevice);

		D3D11_TEXTURE2D_DESC texDesc = {};
		texDesc.ArraySize = 1;
		texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
		texDesc.CPUAccessFlags = 0;
		texDesc.Format = ToDXGIFormat(format);
		texDesc.Width = uWidth;
		texDesc.Height = uHeight;
		texDesc.MipLevels = 1;
		texDesc.SampleDesc.Count = 1;
		texDesc.SampleDesc.Quality = 0;
		texDesc.Usage = D3D11_USAGE_DEFAULT;
		texDesc.MiscFlags = 0;

		D3D11_SUBRESOURCE_DATA subData = {};
		subData.pSysMem = lpData;
		subData.SysMemPitch = (uWidth) * TextureFormat::GetSize(format);
		subData.SysMemSlicePitch = (uWidth * uHeight) * TextureFormat::GetSize(format);
		D3D11_SUBRESOURCE_DATA* lpSubData = NULL;
		if (lpData)
			lpSubData = &subData;

		HRESULT hr = lpCGraphicsDevice->GetDevice()->CreateTexture2D(&texDesc, lpSubData, &m_lpTexture);
		if (FAILED(hr))
			return false;

		hr = lpCGraphicsDevice->GetDevice()->CreateShaderResourceView(m_lpTexture, NULL, &m_lpShaderView);
		if (FAILED(hr))
			return false;

		m_Width = uWidth;
		m_Height = uHeight;
		m_Format = format;
		m_HasData = true;

		return true;
	}

	void CTexture::Update(IGraphicsDevice* lpDevice, UInt32 uSubResource, void* lpData)
	{
		CGraphicsDevice* lpCGraphicsDevice = static_cast<CGraphicsDevice*>(lpDevice);

		UInt32 rowPitch = m_Width * TextureFormat::GetSize(m_Format);
		UInt32 slicePitch = rowPitch * m_Height;

		lpCGraphicsDevice->GetContext()->UpdateSubresource(m_lpTexture, uSubResource, NULL, lpData, rowPitch, slicePitch);
	}

	UInt32 CTexture::GetWidth() const
	{
		return m_Width;
	}
	UInt32 CTexture::GetHeight() const
	{
		return m_Height;
	}
	TextureFormat::Enum	CTexture::GetFormat() const
	{
		return m_Format;
	}
	Bool CTexture::HasData() const
	{
		return m_HasData;
	}

}